package com.pony.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


/**
 * 腾讯云 文件上传与下载
 * @auther pony
 * @create 2023-03-22 18:45
 */
public class TXCloudFileUtils {
    // API 密钥
    private static String secretId = "AKID85nHWWGl11lFUTDhwveCXdU5RYP0MTKv";
    private static String secretKey = "PYR4SiiTyDDxRfeNq30iAMIzQbWCcmgK";
    // 域名
    private static String region = "ap-beijing";
    // 储存桶名称
    private static String bucketName = "pony-1312090731";
    // 路径-访问域名
    private static String path = "https://pony-1312090731.cos.ap-beijing.myqcloud.com";

    /**
     * 初始化COS客户端
     * @return
     */
    public static COSClient initCOSClient() {
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        Region region1 = new Region(region);
        ClientConfig clientConfig = new ClientConfig(region1);
        // 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }

    /**
     * 文件上传
     * PutObjectRequest key 值 文件夹名+文件名 作为key
     * @param file
     */
    public static String upLoad(String imgPath, MultipartFile file) {
        try {
            // 指定要上传到 COS 上对象键，唯一标识
            String key = getFileKey(file.getOriginalFilename());
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, imgPath+key, MultipartFileToFile(file));
            COSClient cosClient1 = initCOSClient();
            // 设置请求头，就可以实现浏览器下载文件时，直接下载文件，而不是跳转
            putObjectRequest.putCustomRequestHeader("Content-Type","application/octet-stream");
            PutObjectResult putObjectResult = cosClient1.putObject(putObjectRequest);
            // 设置权限(公开读)
            cosClient1.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            return key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件下载
     */
    public static void download(String key){
        // 设置要下载到的本地路径
        File downFile = new File("src/main/resources/static/files/images" + key);
        // 设置要下载的文件所在的 对象桶的名称 和对象键
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
        COSClient cosClient1 = initCOSClient();
        ObjectMetadata downObjectMeta = cosClient1.getObject(getObjectRequest, downFile);
    }

    /**
     * 文件删除
     * @param key key 值 文件夹名+文件名 作为key
     */
    public static void del(String key){
        COSClient cosClient1 = initCOSClient();
        // 指定要删除的 bucket 和对象键
        cosClient1.deleteObject(bucketName, key);
    }

    public static void main(String[] args) {
//        download("20230322081658a98ebbd2a94b411b813d0e09c32b7f3a.jpg");
        del("yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg");
//        download();
    }

    /**
     * 生成文件名称
     * 规则：当前时间 + UUID + 文件后缀
     *
     * @param originalFilename 文件原始名称
     * @return
     */
    private static String getFileKey(String originalFilename) {
        //1、获取文件后缀 需要导包 commons-fileupload
        String extension = "." + FilenameUtils.getExtension(originalFilename);
        /*生成新的文件名称 时间 + UUID + 文件后缀
         * replace() UUID 中间有"-"，我们替换成""
         * */
        //获取当前时间，并格式化时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
        String format = simpleDateFormat.format(new Date());
        String newFileName = format + UUID.randomUUID().toString().replace("-", "") + extension;
        return newFileName;
    }

    /**
     * 文件对象转MultipartFile对象
     * @param file 文件
     * @return MultipartFile对象
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItem fileItem = createFileItem(file);
        return new CommonsMultipartFile(fileItem);
    }

    /**
     * 根据File对象创建FileItem对象
     * @param file File
     * @return FileItem对象
     */
    public static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    /**
     * 将MultipartFile转化为 java.io.File
     *
     * @param multipartFile
     * @return
     */
    public static File MultipartFileToFile(MultipartFile multipartFile) {
        // 获取文件名
        String fileName = multipartFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码
        try {
            File file = File.createTempFile(fileName, prefix);
            multipartFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}